
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "platform_inner.h"
#include "platform.h"
#include "klist.h"

static KLIST_INIT(gs_driver_list);
static KLIST_ITER_INIT(gs_driver_list_iter,&gs_driver_list);

static KLIST_INIT(gs_device_list);
static KLIST_ITER_INIT(gs_device_list_iter,&gs_device_list);

static struct file *gs_device_file[32]={0};
static struct file gs_device_file_data[32]={0};

//#define LOG_FILE_NAME "/dev/uart1" //slj change
//#define LOG_FILE_NAME "/dev/uart2" //slj change
//#define LOG_FILE_NAME "/dev/uart3" //slj change
#define LOG_FILE_NAME "/dev/uart4" //slj change

static struct file gs_log_file={0};

struct device * sj_platform_get_device_by_name(const char *name)
{
	struct device *dev = NULL;
	struct klist_node *knode = klist_next(&gs_device_list_iter);

	while(!klist_iter_is_head(&gs_device_list_iter))
	{
		struct device *data = (struct device *)klist_node_get(knode);

		if(data && !strcmp(data->init_name ,name))
		{
			dev = data;
			break;
		}
		knode=klist_next(&gs_device_list_iter);
	}

	klist_iter_exit(&gs_device_list_iter);

	return dev;
}

sj_void sj_platform_device_register(struct klist_node *device)
{
	klist_add_head(device, &gs_device_list);
}

sj_void sj_platform_driver_register(struct klist_node *driver)
{
	klist_add_head(driver, &gs_driver_list);
}

sj_int8 sj_platform_initcall(sj_void)
{
	sj_uint32 dev_id=1,i=0;
    struct device *dev=NULL;
    //driver

    extern struct klist_node * get_key_input_driver_node();
    sj_platform_driver_register(get_key_input_driver_node());

    extern struct klist_node * get_led_driver_node();
    sj_platform_driver_register(get_led_driver_node());


    extern struct klist_node * get_timer_driver_node();
    sj_platform_driver_register(get_timer_driver_node());


    extern struct klist_node * get_lcd_driver_node();
    sj_platform_driver_register(get_lcd_driver_node());

    extern struct klist_node * get_rtc_driver_node(); //slj add
    sj_platform_driver_register(get_rtc_driver_node());

    extern struct klist_node * get_usart_driver_node();
    sj_platform_driver_register(get_usart_driver_node());

    extern struct klist_node * get_io_input_driver_node();
    sj_platform_driver_register(get_io_input_driver_node());

//    extern struct klist_node * get_i2c_driver_node(); //slj add
//    sj_platform_driver_register(get_i2c_driver_node());

    extern struct klist_node * get_iwdg_driver_node(); //slj add
    sj_platform_driver_register(get_iwdg_driver_node());

    extern struct klist_node * get_adc1_driver_node(); //slj add
    sj_platform_driver_register(get_adc1_driver_node());


    //device

    extern struct klist_node * get_uart1_device_node();
    sj_platform_device_register(get_uart1_device_node());

    extern struct klist_node * get_uart4_device_node();
    sj_platform_device_register(get_uart4_device_node());

    extern struct klist_node * get_io_input1_device_node(); //slj change
    sj_platform_device_register(get_io_input1_device_node());

    extern struct klist_node * get_io_input0_device_node(); //slj change
    sj_platform_device_register(get_io_input0_device_node());

    extern struct klist_node * get_io_input2_device_node(); //slj change
    sj_platform_device_register(get_io_input2_device_node());

    extern struct klist_node * get_key_input_device_node();
    sj_platform_device_register(get_key_input_device_node());

    extern struct klist_node * get_lcd_12864_device_node();
    sj_platform_device_register(get_lcd_12864_device_node());

    extern struct klist_node * get_rtc_device_node(); //slj add
    sj_platform_device_register(get_rtc_device_node());

    extern struct klist_node * get_timer3_device_node();
    sj_platform_device_register(get_timer3_device_node());

    extern struct klist_node * get_timer2_device_node();
    sj_platform_device_register(get_timer2_device_node());

    extern struct klist_node * get_timer4_device_node();
    sj_platform_device_register(get_timer4_device_node());

    extern struct klist_node * get_led_green_device_node();
    sj_platform_device_register(get_led_green_device_node());

    extern struct klist_node * get_led_red_device_node();
    sj_platform_device_register(get_led_red_device_node());

    extern struct klist_node * get_uart5_device_node();
    sj_platform_device_register(get_uart5_device_node());

    extern struct klist_node * get_uart2_device_node();
    sj_platform_device_register(get_uart2_device_node());

    extern struct klist_node * get_uart3_device_node();
    sj_platform_device_register(get_uart3_device_node());

//    extern struct klist_node * get_i2c_device_node(); //slj add
//    sj_platform_device_register(get_i2c_device_node());

    extern struct klist_node * get_iwdg_device_node(); //slj add
    sj_platform_device_register(get_iwdg_device_node());

    extern struct klist_node * get_adc1_device_node(); //slj add
    sj_platform_device_register(get_adc1_device_node());


	struct klist_node *knode = klist_next(&gs_device_list_iter);
	while(!klist_iter_is_head(&gs_device_list_iter))
	{
        dev = (struct device *)klist_node_get(knode);
		
		get_device_id(dev) = dev_id++;

		struct klist_node *driver_knode = klist_next(&gs_driver_list_iter);
		while(!klist_iter_is_head(&gs_driver_list_iter))
		{
			struct device_driver *driver_data = (struct device_driver *)klist_node_get(driver_knode);
			struct device_id_table *table =driver_data->id_table;
			int i=0;
			while(table[i].name!=NULL)
			{
				if(!strcmp(table[i].name, dev->compatibility))
				{
					dev->driver = driver_data;
					if(dev->driver->opt && dev->driver->probe)
					{
						dev->driver->probe(dev);
					}
					break;
				}
				i++;
			}
			driver_knode=klist_next(&gs_driver_list_iter);
		}
        if(strcmp(dev->init_name,"/dev/uart2")==0)
        {
            gs_log_file.f_op=get_device_driver_opt(dev->driver);
            gs_log_file.private_data = get_device_data(dev);
        }
		knode=klist_next(&gs_device_list_iter);
	}

	for(i =0;i<32;i++)
	{
		gs_device_file[i] = &gs_device_file_data[i];
	}

	return 0;
}

struct file ** sj_platform_get_global_manager(sj_void)
{	
	return &gs_device_file[0];
}

struct file *sj_platform_log(sj_void)
{
    return &gs_log_file;
}

